<?php
/**
 * @version 	$Id$
 * @author 		Luu Trong Hieu<tronghieu1012@yahoo.com>
 * @copyright 	Copyright (c) 2010 Luu Trong Hieu. All right reserved!
 * @license 	GNU/GPL see license.php
 */

defined('IN_FLYWHEEL') or die('Restricted Access');

/**
 * Flywheel Message
 * 
 * @package 	system
 * @subpackage 	utils
 *
 */
class fMessage {
	const TYPE_SUCCESS = 'SUCCESS';
	const TYPE_WARNING = 'WARNING';
	const TYPE_ERROR = 'ERROR';
	
	private $_type = array(self::TYPE_SUCCESS, self::TYPE_WARNING, self::TYPE_ERROR);
	
	/**
	 * Message Data
	 *
	 * @var array
	 */
	protected $_data = array();
	
	/**
	 * Message object name
	 *
	 * @var string
	 */
	private $_name;
	
	public function __construct($name = null) {
		$this->_name = $name;
		if (sizeof($this->_data) === 0) {
			$this->clear();	
		}
		
		register_shutdown_function(array($this, 'shutdown'));
		$name = 'Message'. ((is_null($name))? '': '.' . $name);				
		$this->_data = fFactory::getSession()->getFlash($name);		
	}
	
	/**
	 * Render
	 *
	 * @param fMessage $msg
	 */
	public static function render(fMessage $msg) {
		$html = '';
		$data = $msg->get();
		if (is_array($data) && sizeof($data) > 0) {
			foreach ($data as $msgGroup => $body) {
				if (is_array($body) && sizeof($body) > 0) {
					$html .= '<dl class="system-message msg-'. strtolower($msgGroup) .'">';
					foreach ($body as $title => $message) {
						$html .= '<dt>' .$title .'</dt>';
						for ($i = 0, $size = sizeof($message); $i<$size; ++$i) {
							$html .= '<dd>' . $message[$i] .'</dd>';										
						}
					}
					$html .= '</dl>';				
				}
			}
		}
		
		return $html;
	}
	
	/**
	 * Add Message
	 *
	 * @param mixed string|fMessage $mess
	 * @param string $type
	 * @param mixed string|array $data
	 * @return boolean
	 */
	public static function addMsg($mess, $type = null, $data = null) {
		if ($mess instanceof fMessage) {			
			$data = $mess->get();
			$name = $mess->getname();
			fFactory::getSession()->setFlash('Message.'.$name, $data);								
		}
		else {
			if ($type == null || $data == null) {
				return false;
			}
			$data = (array) $data;
			$data = array(strtoupper($type) => $data);
			fFactory::getSession()->setFlash('Message.'.$mess, $data);
		}
		
		return true;
	}
	
	/**
	 * Get name
	 * 	get object name
	 *
	 * @return string
	 */
	public function getName() {
		return $this->_name;
	}
	
	/**
	 * Get list type of message
	 * 
	 * @return array
	 */
	public function getTypeList() {
		return $this->_type;		
	}
	
	/**
	 * Check
	 * 	return true if message was set
	 *
	 * @param string $type
	 * @param string $title
	 * @return boolean
	 * @throws fException if type has not set
	 */
	public function check($type, $title = null) {
		$type = strtoupper($type);
		if (!in_array($type, $this->_type)) {
			throw new fException('Dont support message type "' . $title .'"');			
		}		
		if ($title == null) {
			return (boolean) sizeof($this->_data[$type]);
		}
		else {			
			return (boolean) count($this->_data[$type][$title]);
		}
	}
	
	/**
	 * Sum
	 * 	return number of message.
	 *
	 * @param string $type	Type of message, null is return number of all message
	 * @return int
	 * @throws fException if type has not set
	 */
	public function sum($type = null) {
		$type = strtoupper($type);
		if ($type != null) {			
			return count($this->_data[$type]); 
		}
		
		if (!in_array($type, $this->_type)) {
			throw new fException('Dont support message type "' . $type .'"');			
		}
		
		$i = 0;
		for($j = 0, $size = sizeof($this->_data); $j<$size; ++$j) {
			$i += count($this->_data[$i]);
		}
		
		return $i;
	}
	
	/**
	 * Get 
	 *
	 * @param string $type
	 * @return array of messages
	 * @throws fException if type has not set
	 */
	public function get($type = null) {
		$type = strtoupper($type);
		if ($type == null) {
			return $this->_data;		
		}
		else {
			if (!in_array($type, $this->_type)) {
				throw new fException('Dont support message type "' . $type .'"');			
			}
			return $this->_data[$type];
		}
	}
	
	/**
	 * Add message
	 *
	 * @param string $message		Message content
	 * @param string $messageTitle	Message title
	 * @param string $type
	 * @throws fException if type has not set
	 */
	public function add($message, $messageTitle,  $type = 'SUCCESS') {
		$type = strtoupper($type);
		if (!in_array($type, $this->_type)) {
			throw new fException('Dont support message type "' . $type .'"');			
		}

		// handle PEAR errors gracefully
        if ($message instanceof PEAR_Error) {
            $message = $message->getMessage();            
        }
        //Create array of message title
        if (!isset($this->_data[$type][$messageTitle])) {
        	$this->_data[$type][$messageTitle] = array();
        }
        
        //Not repeat message
        if (!in_array($message, $this->_data[$type][$messageTitle])) {
        	$this->_data[$type][$messageTitle][] = $message;
        }
	}
	
	/**
	 * Remove
	 *
	 * @param string $title		Message title
	 * @param string $type		Message type
	 * @throws fException if type has not set
	 */
	public function remove($title, $type) {
		$type = strtoupper($type);
		if (!in_array($type, $this->_type)) {
			throw new fException('Dont support message type "' . $type .'"');			
		}
		unset($this->_data[$type][$title]);	
	}
	
	/**
	 * Clear
	 *
	 */
	private function clear() {
		$type = $this->_type;
		for ($i = 0, $size = sizeof($type); $i < $size; ++$i) {
			$this->_data[$type[$i]] = array();  		
		}
	}
	
	public function shutdown() {
		$name = 'Message' . ((is_null($this->_name))? '' : '.' . $this->_name);		
		fFactory::getSession()->setFlash($name, $this->_data);
	}
}